'use strict';

goog.provide('Blockly.Arduino.mago');

goog.require('Blockly.Arduino');
goog.require('Blockly.JavaScript');

/********************************************
BASE - 基础模块
*********************************************/

  // PWM
  Blockly.Arduino.mg_pwm = function() {
    var dropdown_pin = Blockly.Arduino.valueToCode(this, 'PIN',Blockly.Arduino.ORDER_ATOMIC);
    var value_num = Blockly.Arduino.valueToCode(this, 'NUM', Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.setups_['setup_output_'+dropdown_pin] = 'pinMode('+dropdown_pin+', OUTPUT);';
    var code = 'analogWrite('+dropdown_pin+','+value_num+');\n'
    return code;
  };


  // Buzzer active
  Blockly.Arduino.mg_buzzer = Blockly.Arduino.yf_led;

  // Buzzer Passive
  Blockly.Arduino.yf_buzzer2=function(){
     var dropdown_pin = Blockly.Arduino.valueToCode(this, 'PIN',Blockly.Arduino.ORDER_ATOMIC);
     var fre = Blockly.Arduino.valueToCode(this, 'FREQUENCY',
        Blockly.Arduino.ORDER_ASSIGNMENT) || '0';
     var code="tone("+dropdown_pin+","+fre+");\n";
     Blockly.Arduino.setups_['setup_output_'+dropdown_pin] = 'pinMode('+dropdown_pin+', OUTPUT);';
     return code;
  };
  // Buzzer Passive
  Blockly.Arduino.mg_buzzer3=function(){
     var dropdown_pin = Blockly.Arduino.valueToCode(this, 'PIN',Blockly.Arduino.ORDER_ATOMIC);
     var fre = Blockly.Arduino.valueToCode(this, 'FREQUENCY',
        Blockly.Arduino.ORDER_ASSIGNMENT) || '0';
     var dur = Blockly.Arduino.valueToCode(this, 'DURATION',
        Blockly.Arduino.ORDER_ASSIGNMENT) || '0';
     var code="tone("+dropdown_pin+","+fre+","+dur+");\n";
     Blockly.Arduino.setups_['setup_output_'+dropdown_pin] = 'pinMode('+dropdown_pin+', OUTPUT);';
     return code;
  };

  // Speaker
  Blockly.Arduino.yf_speaker = Blockly.Arduino.yf_buzzer2;
  Blockly.Arduino.yf_speaker2 = Blockly.Arduino.yf_buzzer3;

  
  // DHT11 22
  Blockly.Arduino.yf_dht = function () {
    var sensor_type = this.getFieldValue('TYPE');
    var dropdown_pin = Blockly.Arduino.valueToCode(this, 'PIN', Blockly.Arduino.ORDER_ATOMIC);
    var what = this.getFieldValue('WHAT');
    Blockly.Arduino.definitions_['define_dht'] = '#include <dht.h>';
    Blockly.Arduino.definitions_['var_dht_' + dropdown_pin] = 'dht myDHT_' + dropdown_pin + ';';
    var funcName = 'dht_' + dropdown_pin + '_get' + what;
    var code = 'int' + ' ' + funcName + '() {\n'
      + '  int chk = myDHT_' + dropdown_pin + '.read' + sensor_type + '(' + dropdown_pin + ');\n'
      + '  int value = myDHT_' + dropdown_pin + '.' + what + ';\n'
      + '  return value;\n'
      + '}\n';
    Blockly.Arduino.definitions_[funcName] = code;
    return [funcName + '()', Blockly.Arduino.ORDER_ATOMIC];
  }


  // 微动开关
  Blockly.Arduino.mg_microswitch = function () {
    var dropdown_pin = Blockly.Arduino.valueToCode(this, 'PIN',Blockly.Arduino.ORDER_ATOMIC);
    Blockly.Arduino.setups_['setup_input_'+dropdown_pin] = 'pinMode('+dropdown_pin+', INPUT_PULLUP);';
    var code = 'digitalRead('+dropdown_pin+')';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
  }
    // oled级联地址初始化初始化
    Blockly.Arduino.mg_oleds_init = function () {
      Blockly.Arduino.definitions_['include_SSD1306_I2C'] = '#include "DFRobot_SSD1306_I2C.h"';
      Blockly.Arduino.definitions_['include_I2CMultiplexer'] = '#include "DFRobot_I2CMultiplexer.h"';
      Blockly.Arduino.definitions_['include_Character'] = '#include "DFRobot_Character.h"';
      Blockly.Arduino.definitions_['include_DFRobot_GT30L'] = '#include "DFRobot_GT30L.h"';
      Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
      Blockly.Arduino.definitions_['include_SPI'] = '#include <SPI.h>';
      Blockly.Arduino.definitions_['statement_SSD1306_I2C'] = 'DFRobot_SSD1306_I2C OLED(0x3C);';
      Blockly.Arduino.definitions_['statement_I2CMultiplexer'] = 'DFRobot_I2CMultiplexer  I2CMulti(0x70);';
      Blockly.Arduino.definitions_['remark_pin'] = '/*\n'
      +'ld3320引脚连接图\n'
      +'arduino  --> iic地址拓展版 --> oled\n'
      +'VCC      --> VIN         -->  VCC\n'
      +'GND      --> GND         -->  GND\n'
      +'A4       --> SDA         -->  Not connected不连接\n'
      +'A5       --> SCL         -->  Not connected不连接\n'
      +'连接第一个oled,选择第一个端口\n'
      +'不连接    --> SD0         -->  SDA         \n'
      +'不连接    --> SC0         -->  SCL         \n'
      +'连接第二个oled,选择第二个端口\n'
      +'不连接    --> SD1         -->  SDA         \n'
      +'不连接    --> SC1         -->  SCL         \n'
      +'连接第三个oled,选择第三个端口\n'
      +'不连接    --> SD2         -->  SDA         \n'
      +'不连接    --> SC2         -->  SCL         \n'
      +'连接第四个oled,选择第四个端口\n'
      +'不连接    --> SD3         -->  SDA         \n'
      +'不连接    --> SC3         -->  SCL         \n'
      +'.\n'
      +'.\n'
      +'.\n'
      +'不连接    --> SD7         -->  SDA         \n'
      +'不连接    --> SC7         -->  SCL         \n'
      +'*/';
      var code = '';
      return [code, Blockly.Arduino.ORDER_ATOMIC];
    }

  // 端口
  Blockly.Arduino.mg_oleds_port = function () {
    Blockly.Arduino.definitions_['include_I2CMultiplexer'] = '#include "DFRobot_I2CMultiplexer.h"';
    Blockly.Arduino.definitions_['statement_I2CMultiplexer'] = 'DFRobot_I2CMultiplexer  I2CMulti(0x70);';
    var dropdown_port = Blockly.Arduino.valueToCode(this, 'port', Blockly.Arduino.ORDER_ASSIGNMENT);
    var code = 'I2CMulti.selectPort('+dropdown_port+');\n';
    return code;
  }
  Blockly.Arduino.mg_oleds_cursor = function () {
    var pos_x = Blockly.Arduino.valueToCode(this, 'XVALUE', Blockly.Arduino.ORDER_ASSIGNMENT);
    var pos_y = Blockly.Arduino.valueToCode(this, 'YVALUE', Blockly.Arduino.ORDER_ASSIGNMENT);
    var textString = Blockly.Arduino.valueToCode(this, 'TEXT', Blockly.Arduino.ORDER_ASSIGNMENT);
    var code = 'OLED.setCursor('+pos_x+','+pos_y+');\n'
        +'OLED.print('+textString+');\n'
    ;
    return code;
  }

  // LD3320初始化
  Blockly.Arduino.mg_LD3320_Init = function () {
    Blockly.Arduino.definitions_['include_ld3320'] = '#include <ld3320.h>';
    Blockly.Arduino.definitions_['statement_voiceObject'] = 'VoiceRecognition Voice;';
    Blockly.Arduino.definitions_['remark_pin'] = '/*\n'
    +'ld3320引脚连接图\n'
    +'VCC  --> 3.3V\n'
    +'GND  --> GND\n'
    +'MISO --> D12\n'
    +'MOSI --> D11\n'
    +'SCK  --> D13\n'
    +'CS   --> D4\n'
    +'RST  --> D9\n'
    +'IRQ  --> D2\n'
    +'WR   --> GND\n'
    +'*/';
    Blockly.Arduino.setups_['setup_input_Init'] = 'Voice.init(); //初始化VoiceRecognition模块';
    var code = '';
    return code;
  }
  // LD3320添加指令
  Blockly.Arduino.mg_LD3320_addCommand = function () {
    var value = Blockly.Arduino.valueToCode(this, 'VALUE',Blockly.Arduino.ORDER_ATOMIC);
    var text = Blockly.Arduino.valueToCode(this, 'TEXT',Blockly.Arduino.ORDER_ATOMIC);
    var prefix = Math.floor(Math.random()*10000);
    Blockly.Arduino.setups_['setup_input_addcommand_'+prefix] = 'Voice.addCommand('+text+','+value+');   //添加指令，参数（指令内容，指令标签（可重复））';
    var code = '';
    return code;
  }
  // LD3320开始识别
  Blockly.Arduino.mg_LD3320_Start = function () {
    Blockly.Arduino.setups_['setup_input_Start'] = 'Voice.start();   //开始识别';
    var code = '';
    return code;
  }
  // LD3320读取指令
  Blockly.Arduino.mg_LD3320_getCommand = function () {
    var code = 'Voice.read()';
    return [code, Blockly.Arduino.ORDER_ATOMIC];
  }



/********************************************
Arduino Shield 
*********************************************/
  // Motor drive L298P模块
  Blockly.Arduino.mg_Motor=function(){
    var dropdown_pin = this.getFieldValue('PIN');
    var dropdown_dir = this.getFieldValue('DIR');
    if (dropdown_pin=='1') {
      Blockly.Arduino.setups_['setup_output_2'] = 'pinMode(2, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_3'] = 'pinMode(3, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w2'] = 'digitalWrite(2, LOW);';
      Blockly.Arduino.setups_['setup_output_w3'] = 'digitalWrite(3, LOW);';
    } else if (dropdown_pin=='2') {
      Blockly.Arduino.setups_['setup_output_4'] = 'pinMode(4, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_5'] = 'pinMode(5, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w4'] = 'digitalWrite(4, LOW);';
      Blockly.Arduino.setups_['setup_output_w5'] = 'digitalWrite(5, LOW);';
    } else if (dropdown_pin=='3') {
      Blockly.Arduino.setups_['setup_output_6'] = 'pinMode(6, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_7'] = 'pinMode(7, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w6'] = 'digitalWrite(6, LOW);';
      Blockly.Arduino.setups_['setup_output_w7'] = 'digitalWrite(7, LOW);';
    }else if(dropdown_pin=='4'){
      Blockly.Arduino.setups_['setup_output_8'] = 'pinMode(8, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_9'] = 'pinMode(9, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w8'] = 'digitalWrite(8, LOW);';
      Blockly.Arduino.setups_['setup_output_w9'] = 'digitalWrite(9, LOW);';
    }
    
    var funcName='mago_setMotor';
    var funcCode='void '+funcName+'(int motorId, int motorDir) {\n' 
    + ' int directionPin1, directionPin2;\n'
    + ' if (motorId == 1) {         // motor A\n' 
    + ' directionPin2 = 3;\n' 
    + ' directionPin1 = 2;\n' 
    + ' } else if (motorId == 2) {  // motor B\n'  
    + ' directionPin1 = 5;\n'    
    + ' directionPin2 = 4;\n'    
    + ' } else if (motorId == 3) {  // motor C\n'  
    + ' directionPin1 = 6;\n'    
    + ' directionPin2 = 7;\n'   
    + ' } else if (motorId == 4) {  // motor D\n' 
    + ' directionPin2 = 9;\n'   
    + ' directionPin1 = 8;\n'    
    + ' } else {\n'  
    + ' return;\n'   
    + ' }\n' 
    + ' if(motorDir == 1) {\n'     //正转 
    + ' digitalWrite(directionPin1, LOW);\n'     
    + ' digitalWrite(directionPin2, HIGH);\n'      
    + ' } else if(motorDir == 0) {\n'   //反转  
    + ' digitalWrite(directionPin1, HIGH);\n'    
    + ' digitalWrite(directionPin2, LOW);\n' 
    + ' }\n'
    + ' }\n';
    Blockly.Arduino.definitions_[funcName] = funcCode;
    var code = funcName +'('+ dropdown_pin +','+ dropdown_dir +');\n';
    return code;
  };
  Blockly.Arduino.mg_Motor_pwm=function(){
    var dropdown_pin = this.getFieldValue('PIN');
    var dropdown_dir = this.getFieldValue('DIR');
    var dropdown_speed = Blockly.Arduino.valueToCode(this, 'speed', Blockly.Arduino.ORDER_ASSIGNMENT) || '0';
    if (dropdown_pin=='1') {
      Blockly.Arduino.setups_['setup_output_2'] = 'pinMode(2, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_3'] = 'pinMode(3, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w2'] = 'digitalWrite(2, LOW);';
      Blockly.Arduino.setups_['setup_output_w3'] = 'digitalWrite(3, LOW);';
    } else if (dropdown_pin=='2') {
      Blockly.Arduino.setups_['setup_output_4'] = 'pinMode(4, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_5'] = 'pinMode(5, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w4'] = 'digitalWrite(4, LOW);';
      Blockly.Arduino.setups_['setup_output_w5'] = 'digitalWrite(5, LOW);';
    } else if (dropdown_pin=='3') {
      Blockly.Arduino.setups_['setup_output_6'] = 'pinMode(6, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_7'] = 'pinMode(7, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w6'] = 'digitalWrite(6, LOW);';
      Blockly.Arduino.setups_['setup_output_w7'] = 'digitalWrite(7, LOW);';
    }else if(dropdown_pin=='4'){
      Blockly.Arduino.setups_['setup_output_8'] = 'pinMode(8, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_9'] = 'pinMode(9, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w8'] = 'digitalWrite(8, LOW);';
      Blockly.Arduino.setups_['setup_output_w9'] = 'digitalWrite(9, LOW);';
    }
    var funcName='mago_setMotor_pwm';
    var funcCode='void '+funcName+'(int motorId, int motorDir, int motorSpeed) {\n' 
    + ' int directionPin1, directionPin2;\n'
    + ' if (motorId == 1) {         // motor A\n' 
    + ' directionPin2 = 3;\n' 
    + ' directionPin1 = 2;\n' 
    + ' } else if (motorId == 2) {  // motor B\n'  
    + ' directionPin2 = 5;\n'    
    + ' directionPin1 = 4;\n'    
    + ' } else if (motorId == 3) {  // motor C\n'  
    + ' directionPin2 = 6;\n'    
    + ' directionPin1 = 7;\n'   
    + ' } else if (motorId == 4) {  // motor D\n' 
    + ' directionPin2 = 9;\n'   
    + ' directionPin1 = 8;\n'    
    + ' } else {\n'  
    + ' return;\n'   
    + ' }\n' 
    + ' if(motorDir == 1 && motorId != 4) {\n'     //正转 
    + '   digitalWrite(directionPin1, HIGH);\n'     
    + '   analogWrite(directionPin2, motorSpeed);\n'      
    + ' } else if(motorDir == 0 && motorId != 4) {\n'   //反转  
    + '   digitalWrite(directionPin1, LOW);\n'    
    + '   analogWrite(directionPin2, motorSpeed);\n' 
    + ' }else if(motorDir == 1 && motorId == 4) {\n'
    + '   digitalWrite(directionPin1, LOW);\n'    
    + '   analogWrite(directionPin2, motorSpeed);\n' 
    + '} else if(motorDir == 0 && motorId == 4) {\n'
    + '   digitalWrite(directionPin1, HIGH);\n'     
    + '   analogWrite(directionPin2, motorSpeed);\n' 
    + '}\n'
    + ' }\n';
    Blockly.Arduino.definitions_[funcName] = funcCode;
    var code = funcName +'('+ dropdown_pin +','+ dropdown_dir +','+ dropdown_speed+');\n';
    return code;
  };


  

  Blockly.Arduino.mg_Motor_stop=function(){
    var dropdown_pin = this.getFieldValue('PIN');
    if (dropdown_pin=='1') {
      Blockly.Arduino.setups_['setup_output_2'] = 'pinMode(2, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_3'] = 'pinMode(3, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w2'] = 'digitalWrite(2, LOW);';
      Blockly.Arduino.setups_['setup_output_w3'] = 'digitalWrite(3, LOW);';
    } else if (dropdown_pin=='2') {
      Blockly.Arduino.setups_['setup_output_4'] = 'pinMode(4, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_5'] = 'pinMode(5, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w4'] = 'digitalWrite(4, LOW);';
      Blockly.Arduino.setups_['setup_output_w5'] = 'digitalWrite(5, LOW);';
    } else if (dropdown_pin=='3') {
      Blockly.Arduino.setups_['setup_output_6'] = 'pinMode(6, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_7'] = 'pinMode(7, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w6'] = 'digitalWrite(6, LOW);';
      Blockly.Arduino.setups_['setup_output_w7'] = 'digitalWrite(7, LOW);';
    }else if(dropdown_pin=='4'){
      Blockly.Arduino.setups_['setup_output_8'] = 'pinMode(8, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_9'] = 'pinMode(9, OUTPUT);';
      Blockly.Arduino.setups_['setup_output_w8'] = 'digitalWrite(8, LOW);';
      Blockly.Arduino.setups_['setup_output_w9'] = 'digitalWrite(9, LOW);';
    }
    var funcName='mago_setMotor_stop';
    var funcCode='void '+funcName+'(int motorId, int motorDir) {\n' 
    + 'int directionPin1, directionPin2;\n'
    + 'if (motorId == 1) {         // motor A\n' 
    +  'directionPin2 = 3;\n' 
    +  'directionPin1 = 2;\n' 
    + '} else if (motorId == 2) {  // motor B\n'  
    +  'directionPin2 = 5;\n'    
    +  'directionPin1 = 4;\n'    
    + '} else if (motorId == 3) {  // motor C\n'  
    +  'directionPin2 = 6;\n'    
    +  'directionPin1 = 7;\n'   
    + '} else if (motorId == 4) {  // motor D\n' 
    +  'directionPin2 = 8;\n'   
    + 'directionPin1 = 9;\n'    
    + '} else {\n'  
    + 'return;\n'   
    + '}\n' 
    +  'digitalWrite(directionPin1, LOW);\n'     
    +  'digitalWrite(directionPin2, LOW);\n'  
    + '}\n';
    Blockly.Arduino.definitions_[funcName] = funcCode;
    var code = funcName +'(' + dropdown_pin +',0); \n';
    return code;
  };

  

/********************************************
more - 更多
*********************************************/
 // 红外测温
 Blockly.Arduino.mg_Tempe = function() {
  //var sensor_type = this.getFieldValue('TYPE');
  //var dropdown_pin = Blockly.Arduino.valueToCode(this, 'PIN', Blockly.Arduino.ORDER_ATOMIC);
  //var what = this.getFieldValue('WHAT');
  Blockly.Arduino.definitions_['define_wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['var_result_'] = 'uint16_t' +' '+'result' +';';
  Blockly.Arduino.setups_['setup_output_'] = 'Wire'+'.'+'begin'+'('+')'+';\n';
  var funcName = 'bodyuTemp_func';

  var code = 'float' + ' ' + funcName + '() {\n'
    +' Wire' + '.' + 'beginTransmission' + '('+'0x5A'+')' + ';\n'
    +' Wire'+'.'+'write'+'('+'0x07'+')'+';\n'
    +' Wire'+'.'+'endTransmission'+'('+'false'+')'+';\n'
    +' Wire'+'.'+'requestFrom'+'('+'0x5A'+','+'3'+')'+';\n'
    +' result'+'='+'Wire'+'.'+'read'+'('+')'+';\n'
    +' result'+'|='+'Wire'+'.'+'read'+'('+')'+'<<'+'8'+';\n'
    +' uint8_t' + ' pec'+'='+'Wire'+'.'+'read'+'('+')'+';\n'
    +' return'+' result'+'*'+'0.02'+'-'+'270'+';\n'
    + '}\n';
  Blockly.Arduino.definitions_[funcName] = code;
  return [funcName + '()', Blockly.Arduino.ORDER_ATOMIC];
};


//Max30102心率监测模块
Blockly.Arduino.mg_MAX30102_init = function() {
  var particleSensor = "particleSensor";
  var serial = "Serial";
  Blockly.Arduino.definitions_['include_Wire'] = '#include <Wire.h>';
  Blockly.Arduino.definitions_['include_heartRate'] = '#include <heartRate.h>';
  Blockly.Arduino.definitions_['include_MAX30105'] = '#include <MAX30105.h>';
  Blockly.Arduino.definitions_['var_declare_MAX30105'] = 'MAX30105 '+particleSensor+';';

  Blockly.Arduino.definitions_['var_declare_RATE_SIZE'] = 'const '+ 'byte '+ 'RATE_SIZE '+ '= '+' 4'+' ;'+ '    //Increase this for more averaging. 4 is good.\n';
  Blockly.Arduino.definitions_['var_declare_rates'] = 'byte '+ 'rates[RATE_SIZE]'+ ';'+'     //Array of heart rates\n';
  Blockly.Arduino.definitions_['var_declare_rateSpot'] = 'byte '+ 'rateSpot '+ '= ' +' 0 '+' ;\n';
  Blockly.Arduino.definitions_['var_declare_lastBeat'] = 'long '+ 'lastBeat ' +'= ' +'0 '+' ;'+ '      //Time at which the last beat occurred\n';
  Blockly.Arduino.definitions_['var_declare_beatsPerMinute'] = 'float '+ 'beatsPerMinute '+' ;\n';
  Blockly.Arduino.definitions_['var_declare_beatAvg'] = 'int '+ 'beatAvg '+';\n';

  Blockly.Arduino.setups_['setup_serial_Serial'] = serial + '.begin(9600);\n';
  Blockly.Arduino.setups_['setup_output_1'] = serial + '.println('+ '" Initializing..."'+');\n';

  Blockly.Arduino.setups_['setup_output_2'] ='if'+ ' ('+'!'+ particleSensor +'.begin('+'Wire,'+' I2C_SPEED_FAST))\n'
                                                + '{\n'
                                                +   'Serial.println('+'"MAX30105 was not found. Please check wiring/power. "'+');\n'
                                                +   'while'+' (1);\n'
                                                + '}\n'
                                                
                                                + 'Serial.println('+'"Place your index finger on the sensor with steady pressure."'+');\n'

                                                + particleSensor +'.setup();\n'
                                                + particleSensor +'.setPulseAmplitudeRed(0x0A);\n' 
                                                + particleSensor +'.setPulseAmplitudeGreen(0);\n';
  
  var funcName = 'getIrValue_func';
  var code = 'int' + ' ' + funcName + '() {\n'
  +' long'+' irValue'+' ='+ particleSensor+'.getIR();\n'

  +' if'+' (checkForBeat(irValue)'+' =='+' true'+')\n'
  +' {\n'

    + '   long'+' delta'+' ='+' millis()'+' -'+' lastBeat;\n'
    + '   lastBeat'+' ='+' millis();\n'

    + '   beatsPerMinute'+' ='+' 60'+' /'+' (delta'+' /'+' 1000.0);\n'

    + '   if'+' (beatsPerMinute'+' <'+' 255'+' &&'+' beatsPerMinute'+' >'+' 20)\n'
    +'    {\n'
     + '    rates[rateSpot++]'+' ='+' (byte)beatsPerMinute;\n' 
     + '    rateSpot'+' %='+' RATE_SIZE;\n' 


     + '    beatAvg'+' ='+' 0;\n'
     + '    for'+' (byte'+' x'+' ='+' 0'+' ;'+' x'+' <'+' RATE_SIZE'+' ;'+' x++){\n'
       + '    beatAvg'+' +='+' rates[x];\n'
       +'   }\n'
      + '   beatAvg'+' /='+' RATE_SIZE;\n'
   + '    }\n'
  + ' }\n'
  +'if'+' (irValue'+' <'+' 5000)'+' {\n'
  +' beatAvg'+' ='+' 0;\n'
  +'}\n'
  +'return'+' beatAvg;\n'
  +'//Serial.print(", BPM=");\n'
  +'//Serial.print(beatsPerMinute);\n'
  +'//Serial.print(", Avg BPM=");\n'
  +'//Serial.print(irValue);\n'
  + '}\n';
  Blockly.Arduino.definitions_[funcName] = code;
  return [funcName + '()', Blockly.Arduino.ORDER_ATOMIC];
};



//舵机
Blockly.Arduino.mg_varspeedservo = function () {
  var dropdown_pin = this.getFieldValue('PIN');
  var value_degree = Blockly.Arduino.valueToCode(this, 'DEGREE', Blockly.Arduino.ORDER_ATOMIC) || '0';
  var value_speed = Blockly.Arduino.valueToCode(this, 'SPEED', Blockly.Arduino.ORDER_ATOMIC) || '0'
  Blockly.Arduino.definitions_['include_Servo'] = '#include <VarSpeedServo.h>';
  Blockly.Arduino.definitions_['var_declare_servo' + dropdown_pin] = 'VarSpeedServo varSpeedServo_' + dropdown_pin + ';';
  Blockly.Arduino.setups_['setup_servo_' + dropdown_pin] = 'varSpeedServo_' + dropdown_pin + '.attach(' + dropdown_pin + ');';
  //varSpeedServo_.write(DEGREE,SPEED)#角度,速度
  var code = 'varSpeedServo_' + dropdown_pin + '.write(' + value_degree +','+ value_speed + ');\n';
  return code;
};
Blockly.Arduino.mg_varspeedservobywait = function () {
  var dropdown_pin = this.getFieldValue('PIN');
  //是否等待舵机运行完成
  var code = 'varSpeedServo_' + dropdown_pin + '.wait();\n';
  return code;
};
Blockly.Arduino.mg_varspeedservobystop = function () {
  var dropdown_pin = this.getFieldValue('PIN');
  //将舵机停在当前位置
  var code = 'varSpeedServo_' + dropdown_pin + '.stop();\n';
  return code;
};


 // 读取舵机度数
 Blockly.Arduino.mg_varspeedservobydegree = function() {
  var dropdown_pin = this.getFieldValue('PIN');
  var code = 'varSpeedServo_' + dropdown_pin + '.read()';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};



//TODO　json数据处理
Blockly.Arduino.mg_JSONParse = function () {
  var value_json = Blockly.Arduino.valueToCode(this, 'A', Blockly.Arduino.ORDER_ATOMIC) || '""';
  Blockly.Arduino.definitions_['include_ArduinoJson'] = '#include <ArduinoJson.h>';
  Blockly.Arduino.definitions_['include_FlagJSON'] = '#include <FlagJSON.h>';
  Blockly.Arduino.definitions_['_jsonRoot'] = 'JsonVariant _jsonRoot;';
  Blockly.Arduino.definitions_['_jsonBuffer'] = 'DynamicJsonBuffer _jsonBuffer;';
  
  var code = '_jsonBuffer.clear();\n'
              +'_jsonRoot = _jsonBuffer.parse('+value_json+');\n';
  return code;
};

// 是否成功解析json数据
Blockly.Arduino.mg_JSONSuccess = function() {
  var code = '_jsonRoot'+ '.success()';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

// 获取解析后的json数据
Blockly.Arduino.mg_JSON2Str = function() {
  var value_json = Blockly.Arduino.valueToCode(this, 'STR', Blockly.Arduino.ORDER_ATOMIC) || '""';
  var code = 'flagJSON.getJSONDataAsString(_jsonRoot,'+value_json+ ')';

  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

 ////点阵屏分区域显示字符
 Blockly.Arduino.mg_display_Matrix_DrawPixel = function() {
  var matrixType = this.getFieldValue('TYPE');
  var pos_x = Blockly.Arduino.valueToCode(this, 'XVALUE', Blockly.Arduino.ORDER_ASSIGNMENT);
  var pos_y = Blockly.Arduino.valueToCode(this, 'YVALUE', Blockly.Arduino.ORDER_ASSIGNMENT);
  var textString = Blockly.Arduino.valueToCode(this, 'TEXT', Blockly.Arduino.ORDER_ASSIGNMENT);
  //var matrixName = this.getFieldValue('matrixName');
  var matrixName = "myMatrix";
  var xdropdown_type = Blockly.Arduino.valueToCode(this, 'XSTAT', Blockly.Arduino.ORDER_ATOMIC);
  var ydropdown_type = Blockly.Arduino.valueToCode(this, 'YSTAT', Blockly.Arduino.ORDER_ATOMIC);
  if(matrixType=="HT16K33")
  {
    
  }
  else
  {
    var code =matrixName+ '.drawChar('+pos_x+','+pos_y+','+textString+','+xdropdown_type+','+ydropdown_type+','+1+');\n'
  }
  code+= matrixName +'.write();\n';
  return code;
};


 //TODO esp8266AP模式初始化
 Blockly.Arduino.mg_WIFIAP_Init = function() {
  var matrixName = "wifiManager";
  Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include <ESP8266WiFi.h>';
  Blockly.Arduino.definitions_['include_DNSServer'] = '#include <DNSServer.h>';
  Blockly.Arduino.definitions_['include_ESP8266WebServer'] = '#include <ESP8266WebServer.h>';
  Blockly.Arduino.definitions_['include_WiFiManager'] = '#include <WiFiManager.h>';
  Blockly.Arduino.definitions_['define_WiFiManager'] = '#define BLINKER_ESP_SMARTCONFIG';
  Blockly.Arduino.definitions_['var_declare'+matrixName] = 'void configModeCallback (WiFiManager *myWiFiManager) {\n'
    +'Serial.println(WiFi.softAPIP());\n'
    +'Serial.println(myWiFiManager->getConfigPortalSSID());\n'
    +'}';
  Blockly.Arduino.setups_['setup_' + matrixName] = 'Serial.begin(115200);\n'
  +'  WiFiManager ' + matrixName+';\n'
  +'  wifiManager.setAPCallback(configModeCallback);\n'
  +'  if(!wifiManager.autoConnect()) {\n'
  +'  Serial.println("failed to connect and hit timeout");\n'
  +'  ESP.reset();\n'
  +'  delay(1000);\n'
  +'}\n'
  +'Serial.println("connected...yeey");\n';
  var code = '';
  return code;
};

//检测WiFi是否连接
Blockly.Arduino.mg_checkwifiConnected = function() {
  var code = "wifiManager.autoConnect()";
  return code;
};

//擦除esp8266数据
Blockly.Arduino.mg_deleteesp8266Data = function() {
  var code = 'WiFiManager wifiManager;\n'
              +'wifiManager.resetSettings();\n';
  return code;
};

//连接Blinker只需要密钥
Blockly.Arduino.mg_Blinker_ksljwl = function() {
  var text_szmca = this.getFieldValue('privatekey');
  Blockly.Arduino.setups_['ksljwl'] = 'Blinker.begin('+text_szmca+');';
  var code = '';
  return code;
};



 //获取API状态码
 Blockly.Arduino.mg_connectAPI = function() {
  var url = Blockly.Arduino.valueToCode(this, 'URL', Blockly.Arduino.ORDER_ATOMIC) || '""';
  Blockly.Arduino.definitions_['include_HTTPClient'] = '#include <FlagHTTPClient.h>';
  Blockly.Arduino.definitions_['include_httpClient'] = 'FlagHTTPClient _httpClient;';
  var funcName='_httpGET';
  var funcCode='int '+funcName+'(String url) {\n' 
  +'_httpClient.end();\n'
  +'_httpClient.begin(url);\n'
  +'_httpClient.setTimeout(30000);\n'
  +'return _httpClient.GET();\n'
  + '}\n';
  Blockly.Arduino.definitions_[funcName] = funcCode;

  var code = '_httpGET('+url+')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

 //获取API内容
 Blockly.Arduino.mg_getAPIData = function() {
  var code = '_httpClient.getString()';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};


//TODO 物联网mqtt

var Client_ID ;
Blockly.Arduino.mg_MQTT_server = function() {
  var server_add = Blockly.Arduino.valueToCode(this, 'server_add', Blockly.Arduino.ORDER_ATOMIC);
  var server_port = Blockly.Arduino.valueToCode(this, 'server_port', Blockly.Arduino.ORDER_ATOMIC);
  var IOT_ID = Blockly.Arduino.valueToCode(this, 'IOT_ID', Blockly.Arduino.ORDER_ATOMIC) || '"mg"';
  var IOT_PWD = Blockly.Arduino.valueToCode(this, 'IOT_PWD', Blockly.Arduino.ORDER_ATOMIC) || '"mg"';
  Client_ID = Blockly.Arduino.valueToCode(this, 'Client_ID', Blockly.Arduino.ORDER_ATOMIC);
  if (Client_ID.length>2) 
  {
    Client_ID+='/';
  }
  Client_ID = Client_ID.replace(/\"/g, "");
  Blockly.Arduino.definitions_['include_Adafruit_MQTT'] ='#include "Adafruit_MQTT.h"';
  Blockly.Arduino.definitions_['include_Adafruit_MQTT_Client'] ='#include "Adafruit_MQTT_Client.h"';
  Blockly.Arduino.definitions_['include__WiFiClient'] = 'WiFiClient client;';
  Blockly.Arduino.definitions_['var_declare_Adafruit_MQTT_Client'] ='Adafruit_MQTT_Client mqtt(&client, '+server_add+', '+server_port+', '+IOT_ID+', '+IOT_PWD+');';  
  var board_type=JSFuncs.getPlatform();
  if(board_type.match(RegExp(/ESP8266/)))
  {
    Blockly.Arduino.definitions_['var_declare_ MQTT_connect();'] ='void MQTT_connect();';
  }
  var funcName = 'MQTT_connect';
  var code = 'void' + ' ' + funcName + '() {\n'
  + '  int8_t ret;\n'
  + '  if (mqtt.connected()) {\n'
  + '    return;\n'
  + '  }\n'
  + '  Serial.print("Connecting to MQTT... ");\n'
  + '  uint8_t retries = 3;\n'
  + '  while ((ret = mqtt.connect()) != 0) {\n'
  + '    Serial.println(mqtt.connectErrorString(ret));\n'
  + '    Serial.println("Retrying MQTT connection in 5 seconds...");\n'
  + '    mqtt.disconnect();\n'
  + '    delay(5000);\n'
  + '    retries--;\n'
  + '    if (retries == 0) {\n'
  + '      while (1);\n'
  + '    }\n'
  + '  }\n'
  + '  Serial.println("MQTT Connected!");\n'
  + '}\n';
  Blockly.Arduino.definitions_['var_declare_'+funcName] = code;
  return funcName + '();\n';
};

Blockly.Arduino.MQTT_connect= function() {
  var funcName = 'MQTT_connect';
  var code = 'void' + ' ' + funcName + '() {\n'
  + '  int8_t ret;\n'
  + '  if (mqtt.connected()) {\n'
  + '  return;\n'
  + '  }\n'
  + '  Serial.print("Connecting to MQTT... ");\n'
  + '  uint8_t retries = 3;\n'
  + '  while ((ret = mqtt.connect()) != 0) {\n'
  + '    Serial.println(mqtt.connectErrorString(ret));\n'
  + '    Serial.println("Retrying MQTT connection in 5 seconds...");\n'
  + '    mqtt.disconnect();\n'
  + '    delay(5000);\n'
  + '    retries--;\n'
  + '    if (retries == 0) {\n'
  + '      while (1);\n'
  + '    }\n'
  + '  }\n'
  + '  Serial.println("MQTT Connected!");\n'
  + '}\n';
  return funcName + '();\n';
}
//物联网-发送数据到app

Blockly.Arduino.mg_MQTT_publish = function() {
  var Topic = Blockly.Arduino.valueToCode(this, 'Topic', Blockly.Arduino.ORDER_ATOMIC);
  var data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
  Topic = Topic.replace(/\"/g, "");
  Blockly.Arduino.definitions_['var_declare_Adafruit_MQTT_Publish'+Topic] ='Adafruit_MQTT_Publish '+Topic+' = Adafruit_MQTT_Publish(&mqtt, "'+Client_ID+Topic+'");';
  var code=Topic+'.publish(String('+data+').c_str());\n ';
  return code;
};

Blockly.Arduino.MQTT_subscribe_value = function() {
  var Topic = Blockly.Arduino.valueToCode(this, 'Topic', Blockly.Arduino.ORDER_ATOMIC);
  Topic = Topic.replace(/\"/g, "");
  var code = '(char *)'+Topic+'.lastread';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

Blockly.Arduino.mg_MQTT_subscribe = function () {
    // If/elseif/else condition.
    var n = 0;
    var prefix = Math.floor(Math.random()*10000);
    var argument = Blockly.Arduino.valueToCode(this, 'IF' + n,
      Blockly.Arduino.ORDER_NONE) || 'false';
    var branch = Blockly.Arduino.statementToCode(this, 'DO' + n);
    var code = 'if (subscription'+prefix+' ==&' + argument + ') {\n  ' + branch + '\n  }';
    Blockly.Arduino.definitions_['var_declare_Adafruit_MQTT_Subscribe'+Client_ID+'/'+argument] ='Adafruit_MQTT_Subscribe '+argument+' = Adafruit_MQTT_Subscribe(&mqtt,"'+Client_ID+argument+'");';
    Blockly.Arduino.setups_['setup_mqtt.subscribe'+argument] = 'mqtt.subscribe(&'+argument+');';
    
    for (n = 1; n <= this.elseifCount_; n++) {
      argument = Blockly.Arduino.valueToCode(this, 'IF' + n,
        Blockly.Arduino.ORDER_NONE) || 'false';
      branch = Blockly.Arduino.statementToCode(this, 'DO' + n);
      Blockly.Arduino.definitions_['var_declare_Adafruit_MQTT_Subscribe'+Client_ID+argument] ='Adafruit_MQTT_Subscribe  '+argument+'= Adafruit_MQTT_Subscribe(&mqtt,"'+Client_ID+argument+'");';
      Blockly.Arduino.setups_['setup_mqtt.subscribe'+argument] = 'mqtt.subscribe(&'+argument+');';
      code += ' else if (subscription'+prefix+' ==&' + argument + ') {\n  ' + branch + '\n  }';
    }
    if (this.elseCount_) {
      branch = Blockly.Arduino.statementToCode(this, 'ELSE');
      code += ' else {\n  ' + branch + '\n  }';
    }
    
    return  'Adafruit_MQTT_Subscribe *subscription'+prefix+';\n'
            +'while ((subscription'+prefix+' = mqtt.readSubscription(5000))) {\n  '+code + '\n}\n';
};

Blockly.Arduino.mg_create_array2_with_text = function() {
  var TYPE= this.getFieldValue('TYPE');
  var name= Blockly.Arduino.valueToCode(this, 'name', Blockly.Arduino.ORDER_ATOMIC);
  var s= Blockly.Arduino.valueToCode(this, 'String', Blockly.Arduino.ORDER_ATOMIC);
  s = s.replace(/\"/g, "");
  var code=''+ TYPE+' '+ name+'[]={'+ s+'};\n ';
  return code;
};


//ESP8266 GET请求
Blockly.Arduino.http_get = function () { 
    var api= Blockly.Arduino.valueToCode(this, 'api', Blockly.Arduino.ORDER_ATOMIC);
    var branch = Blockly.Arduino.statementToCode(this, 'success');
    branch = branch.replace(/(^\s*)|(\s*$)/g, "");
    var branch1 = Blockly.Arduino.statementToCode(this, 'failure');
    branch1 = branch1.replace(/(^\s*)|(\s*$)/g, "");
    Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include <ESP8266WiFi.h>';
    Blockly.Arduino.definitions_['include_ESP8266HTTPClient'] = '#include <ESP8266HTTPClient.h>';
    var code='if (WiFi.status() == WL_CONNECTED) {\nHTTPClient http;\nhttp.begin('+ api+');\nint httpCode = http.GET();\nif (httpCode > 0) {\nString Request_result = http.getString();\n' + branch + '\n}\nelse {\n' + branch1 + '\n} \nhttp.end();\n}\n';
    return code;
};


Blockly.Arduino.make_tool_normal = function() {
  var value_data = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
var code = value_data+';\n';
return code;
};

//初始化舵机
Blockly.Arduino.make_arduino_servo_begin = function() {
  this.setTooltip("初始化舵机，返回数据的类型为boolean，成功返回通道号，失败则返回0");
    var text_name = this.getFieldValue('name');
    var value_pin = Blockly.Arduino.valueToCode(this, 'pin', Blockly.Arduino.ORDER_ATOMIC);
  Blockly.Arduino.definitions_['include_'+'VarSpeedServo'] = '#include <VarSpeedServo.h>';
  Blockly.Arduino.definitions_['var_declare_'+text_name] = 'VarSpeedServo '+text_name+';';
  //Blockly.Arduino.setups_['varspeedservo_'+text_name] = text_name+'.attach('+value_pin+');';
  var code = text_name+'.attach('+value_pin+')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//初始化舵机 可设置最小角度和最大角度
Blockly.Arduino.make_arduino_servo_begin_1 = function() {
  this.setTooltip("初始化舵机，返回数据的类型为boolean，成功返回通道号，失败则返回0");
    var text_name = this.getFieldValue('name');
    var value_pin = Blockly.Arduino.valueToCode(this, 'pin', Blockly.Arduino.ORDER_ATOMIC);
    var value_min = Blockly.Arduino.valueToCode(this, 'min', Blockly.Arduino.ORDER_ATOMIC);
    var value_max = Blockly.Arduino.valueToCode(this, 'max', Blockly.Arduino.ORDER_ATOMIC);
  Blockly.Arduino.definitions_['include_'+'VarSpeedServo'] = '#include <VarSpeedServo.h>';
  Blockly.Arduino.definitions_['var_declare_'+text_name] = 'VarSpeedServo '+text_name+';';
  //Blockly.Arduino.setups_['varspeedservo_'+text_name] = text_name+'.attach('+value_pin+', '+value_min+', '+value_max+');';
  var code = text_name+'.attach('+value_pin+', '+value_min+', '+value_max+')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//舵机 设置角度
Blockly.Arduino.make_arduino_servo_write = function() {
  this.setTooltip("舵机 设置当前的角度(0~180°)，输入值超出544视为脉冲宽度，小于则视为角度，不阻塞程序运行");
    var text_name = this.getFieldValue('name');
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
  var code = text_name+'.write('+value_value+');\n';
  return code;
};

//舵机 设置角度和速度
Blockly.Arduino.make_arduino_servo_write_1 = function() {
  this.setTooltip("舵机 设置当前的角度(0~180°)，输入值超出544视为脉冲宽度，小于则视为角度，不阻塞程序运行");
    var text_name = this.getFieldValue('name');
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var value_speed = Blockly.Arduino.valueToCode(this, 'speed', Blockly.Arduino.ORDER_ATOMIC);
  var code = text_name+'.write('+value_value+', '+value_speed+');\n';
  return code;
};

//舵机 设置角度和速度以及选择是否阻塞
Blockly.Arduino.make_arduino_servo_write_2 = function() {
  this.setTooltip("舵机 设置当前的角度(0~180°)，输入值超出544视为脉冲宽度，小于则视为角度");
    var text_name = this.getFieldValue('name');
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var value_speed = Blockly.Arduino.valueToCode(this, 'speed', Blockly.Arduino.ORDER_ATOMIC);
    var value_wait = Blockly.Arduino.valueToCode(this, 'wait', Blockly.Arduino.ORDER_ATOMIC);
  var code = text_name+'.write('+value_value+', '+value_speed+', '+value_wait+');\n';
  return code;
};

//舵机 设置脉冲宽度
Blockly.Arduino.make_arduino_servo_writeMicroseconds = function() {
  this.setTooltip("舵机 设置脉冲宽度，默认的最小脉宽为544微秒，最大脉宽为2400微秒");
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var text_name = this.getFieldValue('name');
  var code = text_name+'.writeMicroseconds('+value_value+');\n';
  return code;
};

//舵机 获取数据
Blockly.Arduino.make_arduino_servo_read = function() {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
  if(dropdown_type == 'read')
    this.setTooltip("舵机 获取当前角度，返回数据的类型为int");
  else if(dropdown_type == 'readMicroseconds')
    this.setTooltip("舵机 获取当前脉宽，返回数据的类型为int");
  else if(dropdown_type == 'isMoving')
    this.setTooltip("舵机 正在移动?，返回数据的类型为boolean");
  else
    this.setTooltip("舵机 舵机连上控制管脚?，返回数据的类型为boolean");
  var code = text_name+'.'+dropdown_type+'()';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//舵机 执行某些函数
Blockly.Arduino.make_arduino_servo_set = function() {
    var text_name = this.getFieldValue('name');
    var dropdown_type = this.getFieldValue('type');
  if(dropdown_type == 'stop')
    this.setTooltip("舵机 停止移动");
  else if(dropdown_type == 'wait')
    this.setTooltip("舵机 等待移动完成");
  else if(dropdown_type == 'sequenceStop')
    this.setTooltip("舵机 停止执行动作组");
  else
    this.setTooltip("舵机 释放管脚");
  var code = text_name+'.'+dropdown_type+'();\n';
  return code;
};

//舵机 建立一个动作组
Blockly.Arduino.make_arduino_servo_action_group = function() {
    var text_name = this.getFieldValue('name');
    var statements_data = Blockly.Arduino.statementToCode(this, 'data');
  if(statements_data)
    statements_data = statements_data.substring(2,statements_data.length-1);
  Blockly.Arduino.definitions_['include_'+'VarSpeedServo'] = '#include <VarSpeedServo.h>';
  Blockly.Arduino.definitions_['var_declare_'+text_name] = 'servoSequencePoint '+text_name+'[] = {'+statements_data+'};';
  var code = '';
  return code;
};

//舵机 动作组里数据定义
Blockly.Arduino.make_arduino_servo_action_group_data = function() {
    var text_angle = this.getFieldValue('angle');
    var text_speed = this.getFieldValue('speed');
  var surround_parent = this.getSurroundParent();
  var code = '';
  if(surround_parent && surround_parent.type == 'make_arduino_servo_action_group')
  {
    this.setWarningText(null);
    code = '{'+text_angle+','+text_speed+'},';
  }
  else
  {
    this.setWarningText("此块需放到创建动作组块下");
  }
  return code;
};

//舵机 循环执行某一动作组
Blockly.Arduino.make_arduino_servo_sequencePlay = function() {
  this.setTooltip("舵机 从索引为0的动作开始，循环执行某一动作组里的动作，返回数据的类型为uint8_t");
    var text_name = this.getFieldValue('name');
    var value_sequencein = Blockly.Arduino.valueToCode(this, 'sequencein', Blockly.Arduino.ORDER_ATOMIC);
    var value_numpositions = Blockly.Arduino.valueToCode(this, 'numpositions', Blockly.Arduino.ORDER_ATOMIC);
  var code = text_name+'.sequencePlay('+value_sequencein+', '+value_numpositions+')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//舵机 执行某一动作组，可设置是否循环
Blockly.Arduino.make_arduino_servo_sequencePlay_1 = function() {
  this.setTooltip("舵机 从某个索引的动作开始，执行某一动作组里的动作，返回数据的类型为uint8_t");
    var text_name = this.getFieldValue('name');
    var value_sequencein = Blockly.Arduino.valueToCode(this, 'sequencein', Blockly.Arduino.ORDER_ATOMIC);
    var value_numpositions = Blockly.Arduino.valueToCode(this, 'numpositions', Blockly.Arduino.ORDER_ATOMIC);
    var value_loop = Blockly.Arduino.valueToCode(this, 'loop', Blockly.Arduino.ORDER_ATOMIC);
    var value_startPos = Blockly.Arduino.valueToCode(this, 'startPos', Blockly.Arduino.ORDER_ATOMIC);
  var code = text_name+'.sequencePlay('+value_sequencein+', '+value_numpositions+', '+value_loop+', '+value_startPos+')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

//for
Blockly.Arduino.make_for = function() {
  var value_variate = Blockly.Arduino.valueToCode(this, 'variate', Blockly.Arduino.ORDER_ATOMIC);
  var value_judge = Blockly.Arduino.valueToCode(this, 'judge', Blockly.Arduino.ORDER_ATOMIC);
  var value_operation = Blockly.Arduino.valueToCode(this, 'operation', Blockly.Arduino.ORDER_ATOMIC);
  var statements_do = Blockly.Arduino.statementToCode(this, 'do');  
var code = 'for('+value_variate+'; '+value_judge+'; '+value_operation+')\n'
          +'{\n'
          +''+statements_do
          +'}\n';
return code;
};


// PS2 Controller init
Blockly.Arduino.mg_ps2_init = function() {
  var PS2_DAT = Blockly.Arduino.valueToCode(this, 'PIN1', Blockly.Arduino.ORDER_ATOMIC || '10');
  var PS2_CMD = Blockly.Arduino.valueToCode(this, 'PIN2', Blockly.Arduino.ORDER_ATOMIC || '11');
  var PS2_CS = Blockly.Arduino.valueToCode(this, 'PIN3', Blockly.Arduino.ORDER_ATOMIC || '12');
  var PS2_CLK = Blockly.Arduino.valueToCode(this, 'PIN4', Blockly.Arduino.ORDER_ATOMIC || '13');
  Blockly.Arduino.definitions_['include_ps2'] = '#include <PS2X_lib.h>';
  Blockly.Arduino.definitions_['define_ps2_dat'] = '#define PS2_DAT '+ PS2_DAT;
  Blockly.Arduino.definitions_['define_ps2_cmd'] = '#define PS2_CMD '+ PS2_CMD;
  Blockly.Arduino.definitions_['define_ps2_cs'] = '#define PS2_CS '+ PS2_CS;
  Blockly.Arduino.definitions_['define_ps2_clk'] = '#define PS2_CLK '+ PS2_CLK;
  Blockly.Arduino.definitions_['var_ps2x'] = 'PS2X ps2x;';
  Blockly.Arduino.definitions_['var_error'] = 'int error = 0;';
  Blockly.Arduino.definitions_['var_type'] = 'byte type = 0;';
  Blockly.Arduino.definitions_['var_vibrate'] = 'byte vibrate = 0;';
  
  Blockly.Arduino.setups_['setup_init_ps2'] = 'ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_CS, PS2_DAT, true, true);\n';
  Blockly.Arduino.setups_['setup_init_ps2_type'] = 'ps2x.readType();\n';
  return '';

};

// PS2 Controller button
Blockly.Arduino.mg_ps2_btn = function() {
  var PS2_BTN = Blockly.Arduino.variableDB_.getName(this.getFieldValue('PS2_BTN'), Blockly.Variables.NAME_TYPE);
  var PS2_BTN_STATUS = Blockly.Arduino.variableDB_.getName(this.getFieldValue('PS2_BTN_STATUS'), Blockly.Variables.NAME_TYPE);
  var code = 'ps2x.'+ PS2_BTN_STATUS + '(' + PS2_BTN + ')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

// PS2 Controller Rocker
Blockly.Arduino.mg_ps2_rocker = function() {
  // var PS2_ROCKER_STATUS = this.getFieldValue('PS2_ROCKER_STATUS');
  var PS2_ROCKER_STATUS = Blockly.Arduino.variableDB_.getName(this.getFieldValue('PS2_ROCKER_STATUS'), Blockly.Variables.NAME_TYPE);
  var code = 'ps2x.Analog('+ PS2_ROCKER_STATUS + ')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

// PS2 Controller read analog value of the button  --- how hard you press the button
Blockly.Arduino.mg_ps2_a_btn = function() {
  var PS2_A_BTN = this.getFieldValue('PS2_A_BTN');
  var code = 'ps2x.Analog('+ PS2_A_BTN + ')';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};

// PS2 Controller read controller and setmotor
Blockly.Arduino.mg_ps2_readController_setMotoron = function() {
  var PS2_Motor1 = 'true';
  var PS2_Motor2 = '1';
  var code = 'ps2x.read_gamepad('+ PS2_Motor1 + ',' + PS2_Motor2 +');    //开启震动必须在后面加延时50ms   \n '
  return code;
};
Blockly.Arduino.mg_ps2_readController_setMotoroff = function() {
  var PS2_Motor1 = 'false';
  var PS2_Motor2 = '0';
  var code = 'ps2x.read_gamepad('+ PS2_Motor1 + ',' + PS2_Motor2 +');\n'
  return code;
};



//TODO 智慧家居
//RGB
Blockly.Arduino.mg_rgb2on=function(){
  var pin = "A4";  //引脚
  var  value_ledcount = Blockly.Arduino.valueToCode(this, 'PIN1', Blockly.Arduino.ORDER_ATOMIC); 
  var  dropdown_time = Blockly.Arduino.valueToCode(this, 'PIN2', Blockly.Arduino.ORDER_ATOMIC);
  var colour_rgb_led_color = this.getFieldValue('RGB_LED_COLOR');
  Blockly.Arduino.definitions_['include_display'] = '#include "Adafruit_NeoPixel.h"';
  Blockly.Arduino.definitions_['var_rgb_display'] = 'Adafruit_NeoPixel  rgb_display' + '(' + value_ledcount + ',' + pin + ');';
  Blockly.Arduino.setups_['setup_rgb_displaybegin_'] = 'rgb_display.begin();';
  Blockly.Arduino.setups_['setup_rgb_display_initshow'] = 'rgb_display.show();  // Initialize all pixels to off';

  var color = goog.color.hexToRgb(colour_rgb_led_color);
  var code = 'for( int i = 0 ;'+'i < '+(value_ledcount)+'; i++ )\n'
          +'{\n'
          +'  rgb_display'+'.setPixelColor(i, '+color+');\n'
          +'  delay('+ dropdown_time +');\n'
          +'  rgb_display'+'.show();\n'  
          +'}\n';
  return code;
};

Blockly.Arduino.mg_rgb2off=function(){
  var  value_ledcount = Blockly.Arduino.valueToCode(this, 'PIN1', Blockly.Arduino.ORDER_ATOMIC); 
  var  dropdown_time = Blockly.Arduino.valueToCode(this, 'PIN2', Blockly.Arduino.ORDER_ATOMIC);

  var code = 'for( int i = '+ value_ledcount +' ;'+'i >= 0 ; i-- )\n'
          +'{\n'
          +'  rgb_display'+'.setPixelColor(i, 0,0,0);\n'
          +'  delay('+ dropdown_time +');\n'
          +'  rgb_display'+'.show();\n'  
          +'}\n';
  return code;
};
Blockly.Arduino.mg_rgb2on_low=function(){
  var pin = "A4";  //引脚
  var  value_ledcount = Blockly.Arduino.valueToCode(this, 'PIN1', Blockly.Arduino.ORDER_ATOMIC); 
  var dropdown_type = this.getFieldValue('SPEED');
  var dropdown_color = this.getFieldValue('COLOR');
  var type = 'delay(50);\n';
  if(dropdown_type == 'low')
    type='delay(150);\n';
  else if(dropdown_type == 'middle')
    type='delay(100);\n';
  else if(dropdown_type == 'fast'){
    type='delay(50);\n';
  }
  
  Blockly.Arduino.definitions_['include_display'] = '#include "Adafruit_NeoPixel.h"';
  Blockly.Arduino.definitions_['var_rgb_display'] = 'Adafruit_NeoPixel  rgb_display' + '(' + value_ledcount + ',' + pin + ');';
  Blockly.Arduino.setups_['setup_rgb_displaybegin_'] = 'rgb_display.begin();';
  Blockly.Arduino.setups_['setup_rgb_display_initshow'] = 'rgb_display.show();  // Initialize all pixels to off';

  var  light_part='  rgb_display.setPixelColor(j, i,i,i);\n';
  var show_part = '  rgb_display'+'.show();\n';
  if(dropdown_color == 'R')
  light_part='  rgb_display.setPixelColor(j, i,0,0);\n';
  else if(dropdown_color == 'G')
  light_part='  rgb_display.setPixelColor(j, 0,i,0);\n';
  else if(dropdown_color == 'B'){
    light_part='  rgb_display.setPixelColor(j, 0,0,i);\n';
  }else if(dropdown_color == 'W'){
    light_part='  rgb_display.setPixelColor(j, i,i,i);\n';
  }

  var code = 'for(int i = 0 ;'+'i < 255; i++ )\n'
          +'{  \n'
          +'  for(int j = 0 ;'+'j < '+(value_ledcount)+'; j++ )\n'
          +'{  \n'
          + light_part
          + show_part 
          +'  }\n'
          + type
          +'}\n';
  
  return code;
};
Blockly.Arduino.mg_rgb2off_low=function(){
  var  value_ledcount = Blockly.Arduino.valueToCode(this, 'PIN1', Blockly.Arduino.ORDER_ATOMIC); 
  var dropdown_type = this.getFieldValue('SPEED');
  var dropdown_color = this.getFieldValue('COLOR');
  var type = 'delay(50);\n';
  if(dropdown_type == 'low')
    type='delay(150);\n';
  else if(dropdown_type == 'middle')
    type='delay(100);\n';
  else if(dropdown_type == 'fast'){
    type='delay(50);\n';
  }
  var  light_part='  rgb_display.setPixelColor(j, i,i,i);\n';
  var show_part = '  rgb_display'+'.show();\n';
  if(dropdown_color == 'R')
  light_part='  rgb_display.setPixelColor(j, i,0,0);\n';
  else if(dropdown_color == 'G')
  light_part='  rgb_display.setPixelColor(j, 0,i,0);\n';
  else if(dropdown_color == 'B'){
    light_part='  rgb_display.setPixelColor(j, 0,0,i);\n';
  }else if(dropdown_color == 'W'){
    light_part='  rgb_display.setPixelColor(j, i,i,i);\n';
  }

  var code = 'for(int i = 255 ;'+'i >= 0; i-- )\n'
          +'{  \n'
          +'  for(int j = 0 ;'+'j < '+(value_ledcount)+'; j++ )\n'
          +'{  \n'
          + light_part
          + show_part 
          +'  }\n'
          + type
          +'}\n';
  
  return code;
};



Blockly.Arduino.mg_raindrops = function() {

  Blockly.Arduino.setups_['setup_output_'] = 'pinMode(A2, INPUT);';

  var code = '!digitalRead(A2)';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.mg_lightcontrol = function() {
 
  Blockly.Arduino.setups_['setup_output_'] = 'pinMode(A1, INPUT);';

  var code = 'digitalRead(A1)';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};
Blockly.Arduino.mg_touchmodule = function() {
 
  Blockly.Arduino.setups_['setup_output_'] = 'pinMode(A3, INPUT);';

  var code = 'digitalRead(A3)';
  return [code, Blockly.Arduino.ORDER_ATOMIC];
};


//舵机 设置角度和速度
Blockly.Arduino.mg_servo_write_smarthome = function() {
  this.setTooltip("舵机 设置当前的角度(0~180°)，输入值超出544视为脉冲宽度，小于则视为角度，不阻塞程序运行");
    var text_name = this.getFieldValue('name');
    var value_pin = Blockly.Arduino.valueToCode(this, 'pin', Blockly.Arduino.ORDER_ATOMIC);
    var value_value = Blockly.Arduino.valueToCode(this, 'value', Blockly.Arduino.ORDER_ATOMIC);
    var value_speed = Blockly.Arduino.valueToCode(this, 'speed', Blockly.Arduino.ORDER_ATOMIC);


    Blockly.Arduino.definitions_['include_'+'VarSpeedServo'] = '#include <VarSpeedServo.h>';
    Blockly.Arduino.definitions_['var_declare_'+text_name] = 'VarSpeedServo '+text_name+';';
    //Blockly.Arduino.setups_['varspeedservo_'+text_name] = text_name+'.attach('+value_pin+');';
    var code = text_name+'.attach('+value_pin+');\n';
        code += text_name+'.write('+value_value+', '+value_speed+');\n';
        code += text_name+'.wait();\n';
        code += text_name+'.detach();\n';
    return code;
};